#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unordered_map>
#include <iostream>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <fcntl.h>      // for fcntl
#include <sys/types.h>  // for types
#include <sys/socket.h> // for socket functions
#include "logger/Logger.h"
#include "utils/IoBuffer.h"
#include "utils/EventController.h"
#include "session/Session.h"
#include "utils/EventController.h"

#define MAX_EVENTS 1024
// 全局数组来存储连接状态，实际应用中可能需要动态数据结构
// connection_state connections[MAX_CONNECTIONS];

// 使用unordered_map来存储连接状态
//std::unordered_map<int, Session*> session_map;

// 通过文件描述符找到连接状态
//Session* get_connection_state(int fd) {
//
//    for (const auto& pair : session_map) {
//        std::cout << "Key: " << pair.first << " Value: " << pair.second << std::endl;
//    }
//    auto it = session_map.find(fd);
//    if (it != session_map.end()) {
//        return it->second;
//    }
//    return nullptr;
//}
//
//// 添加新的连接状态
//void add_connection_state(int fd) {
//    session_map[fd] = new Session(fd);
//}
//
//// 移除连接状态
//void remove_connection_state(int fd) {
//    auto it = get_connection_state(fd);
//    if (it){
//        delete it;
//    }
//    session_map.erase(fd); // 直接移除元素
//}


int main(int argc, char *argv[]) {

    LOG_INFO("Application is starting");
    LOG_WARNING("This is a warning message");
    LOG_ERROR("This is an error message");


    int server_fd, client_fd, epoll_fd;
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_addr_len;
    struct epoll_event ev, events[MAX_EVENTS];
    int nfds, i;
//    char read_buf[READ_BUF_SIZE+1];

    // 创建EventController对象
    EventController *eventController = new EventController();

    // 创建socket
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd == -1) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // 设置socket选项，允许端口快速重用
    int opt = 1;
    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    // 绑定地址和端口
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(8080);

    if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // 开始监听
    if (listen(server_fd, SOMAXCONN) == -1) {
        perror("listen failed");
        exit(EXIT_FAILURE);
    }

    // 创建epoll实例
    epoll_fd = epoll_create1(0);
    if (epoll_fd == -1) {
        perror("epoll_create1 failed");
        exit(EXIT_FAILURE);
    }

    // 添加服务器socket到epoll实例中
    ev.events = EPOLLIN;
    ev.data.fd = server_fd;
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &ev) == -1) {
        perror("epoll_ctl: server_fd");
        exit(EXIT_FAILURE);
    }

    eventController->server_fd = server_fd;
    // eventController->client_fd = client_fd;
    eventController->epoll_fd = epoll_fd;

    while (1) {
        // 等待事件发生
        nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
        printf("wating...\n");
        if (nfds == -1) {
            perror("epoll_wait");
            exit(EXIT_FAILURE);
        }

        for (i = 0; i < nfds; ++i) {
            if (events[i].data.fd == server_fd) {
                // 有新的连接
                printf("have a content\n");
                client_addr_len = sizeof(client_addr);
                client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_addr_len);
                if (client_fd == -1) {
                    perror("accept");
                    exit(EXIT_FAILURE);
                }

                // 添加连接状态信息
                eventController->handleNewConnection(client_fd); // 假设这个方法已经实现
//                add_connection_state(client_fd);


                // 设置非阻塞模式
                int flags = fcntl(client_fd, F_GETFL, 0);
                fcntl(client_fd, F_SETFL, flags | O_NONBLOCK);

                // 添加新的客户端socket到epoll实例中
                ev.events = EPOLLIN | EPOLLET;
                ev.data.fd = client_fd;
                if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &ev) == -1) {
                    perror("epoll_ctl: client_fd");
                    exit(EXIT_FAILURE);
                }
            }  else if (events[i].events & EPOLLOUT) {
                // socket准备好写入数据
                // 在这里写入数据到socket
                // ...
                LOG_INFO("get_ EPOLLOUT _state");




                Session* session = eventController->get_connection_state(events[i].data.fd);
                if(eventController->CheckSendIoBuffer(session->fd)==0)
                {
                    // 停止监听EPOLLOUT事件,若未发送完成会设置回去的
                    ev.events = EPOLLIN | EPOLLET; // 修改为只监听输入事件
                    ev.data.fd = events[i].data.fd;
                    if (epoll_ctl(epoll_fd, EPOLL_CTL_MOD, events[i].data.fd, &ev) == -1) {
                        perror("epoll_ctl: mod");
                    }
                }

                // 你可以在这里修改感兴趣的事件或者删除对该socket的监听
            } else {
                // 处理客户端发来的数据

                LOG_INFO("get_connection_state");
                Session* session = eventController->get_connection_state(events[i].data.fd);
                IoBuffer* recvBuffer = session->getRecvBuffer();
                LOG_INFO("get_connection_state success");
//                connection_state* state = get_connection_state(events[i].data.fd);
                if (!session) {
                    // 错误处理: 找不到连接状态
                    LOG_WARNING("找不到连接状态");
                    continue;
                }

                // 处理客户端发来的数据
                //ssize_t count = read(events[i].data.fd, state->read_buf + state->buf_len, READ_BUF_SIZE - state->buf_len);
                // 处理客户端发来的数据
                size_t count;
                // while ((count = read(events[i].data.fd, ioBuffer->getWriteIndexP(), ioBuffer->getRemainLen())) > 0) {
                bool full_sign = false;
                do{
                    std::cout<<"before read"<<std::endl;
                    count = read(events[i].data.fd, rexPcvBuffer->getWriteInde(), recvBuffer->getRemainLen());
                    if (count<=0)
                    {
                        break;
                    }
                    recvBuffer->position += (int)count;
                    if(recvBuffer->getRemainLen()==0)
                    {
                        full_sign = true;
                    }else{
                        full_sign = false;
                    }
//                    state->buf_len += count;
//                    // 确保缓冲区不会溢出
//                    if (state->buf_len >= READ_BUF_SIZE) {
//                        // 缓冲区已满，处理已接收的数据或扩展缓冲区
//                        break;
//                    }

                    //暂时处理为只有一条
                    std::cout <<  "recvBuffer->getString(4)" <<  std::endl;

                    recvBuffer->filp();
                    recvBuffer->markPos();
//                    std::cout <<  recvBuffer->getString(count) <<  std::endl;


                    std::cout << "recvBuffer->getInt();:" << std::endl;
                    int type = recvBuffer->getInt();
                    std::cout << "type:" << type <<std::endl;
                    int packLen = 0;
                    int bufferLen = 0;
                    int seq = 0;
                    int uid = 0;
                    switch (type) {
                        case 1:
                            if(recvBuffer->getBufferLen() < 4)
                            {
                                recvBuffer->remarkPos();
                                break;
                            }
                            packLen = recvBuffer->getInt();
                            // std::cout << "packLen:" << packLen <<std::endl;
                            bufferLen = recvBuffer->getBufferLen();
                            // std::cout << "bufferLen:" << bufferLen <<std::endl;
                            if (bufferLen>=packLen){
//                                recvBuffer->remarkPos();
                                eventController->handleRecvEvent(events[i].data.fd,recvBuffer->getString(packLen));
                            }
                            // recvBuffer->getString(packLen);
                            break;
                        case 2:
                            if(recvBuffer->getBufferLen() < 16)
                            {
                                recvBuffer->remarkPos();
                                break;
                            }
                            // seq = recvBuffer->getInt();
                            // uid = recvBuffer->getInt();
                            // packLen = recvBuffer->getInt();
                            // std::cout << "packLen:" << packLen <<std::endl;
                            // std::cout << "bufferLen:" << bufferLen <<std::endl;

                            Json::Value* root = new Json::Value();
                            (*root)["action"] = recvBuffer->getInt();
                            (*root)["seq"] = recvBuffer->getInt();;
                            (*root)["uid"] = recvBuffer->getInt();;
                            packLen = recvBuffer->getInt();
                            (*root)["packLen"] = packLen;
                            std::cout<<"(*root)[action]"<< (*root)["action"].asInt()<<std::endl;
                            std::cout<<"(*root)[seq]"<< (*root)["seq"].asInt()<<std::endl;
                            std::cout<<"(*root)[uid] "<< (*root)["uid"].asInt()<<std::endl;
                            std::cout<<"(*root)[packLen]"<< (*root)["packLen"].asInt()<<std::endl;

                            bufferLen = recvBuffer->getBufferLen();
                            if (bufferLen>=packLen){
//                                recvBuffer->remarkPos();
                                eventController->handleRecvEvent(events[i].data.fd, root,recvBuffer->getString(packLen));
                            }else
                            {
                                recvBuffer->remarkPos();
                            }
                            // recvBuffer->getString(packLen);
                            break;
                        eventController->handleErrorEvent(events[i].data.fd);

                    }

                    // eventController->handleRecvEvent(events[i].data.fd);
                    recvBuffer->compact();

                    std::cout << "count:" << count << std::endl;

//                    state->buf_len += count;
//                    char ss[3];
//                    ss[0] ='\n';
//                    ss[1] ='a';
//                    ss[1] ='b';
//                    printf("test: %.*s\n",2, ss);
//                    // printf("test: %s\n",state->buf_len);?
//                    std::cout << state->buf_len<<":";
//                    std::cout.write(state->read_buf,state->buf_len);
//                    std::cout << std::endl;
//                    printf("get a msg: %.*s\n",(int)state->buf_len, state->read_buf);

                    // 发送回客户端
//                    write(events[i].data.fd, state->read_buf, state->buf_len);

                }while (full_sign==true);


//                (state->read_buf + state->buf_len)[state->buf_len] = '\0';
                if (count == -1) {
                    perror("read");
                    close(events[i].data.fd);
                } else if (count == 0) {
                    // 客户端关闭连接&...
                    // remove_connection_state(events[i].data.fd);
                    // close(events[i].data.fd);
                    // printf("have a close\n");
                } else {

                    // 处理客户端发来的数据
/*                    state->buf_len += count;
                    char ss[3];
                    ss[0] ='\n';
                    ss[1] ='a';
                    ss[1] ='b';
                    printf("test: %.*s\n",2, ss);
                    // printf("test: %s\n",state->buf_len);?
                    std::cout << state->buf_len<<":";
                    std::cout.write(state->read_buf,state->buf_len);
                    std::cout << std::endl;
                    printf("get a msg: %.*s\n",(int)state->buf_len, state->read_buf);


                    // 发送回客户端
                    write(events[i].data.fd, state->read_buf, state->buf_len);*/
                }
            }
        }
    }

    close(server_fd);
    return 0;
}

